package com.vmj.heap;

import com.vmj.classfile.entity.MemberInfo;

/**
 * Created by yangshoujun on 2017/8/26 下午12:27.
 */
public class ClassMember {

    protected int accessFlags;
    protected String name;
    protected String descriptor;
    protected String signature;
    protected VMClass clazz;
    protected byte[] annotationData;

    public void copyMemberInfo(MemberInfo memberInfo) {
        this.accessFlags = memberInfo.getAccessFlags();
        this.name = memberInfo.getName();
        this.descriptor = memberInfo.getDescriptor();
    }

    public boolean isAccessibleTo(VMClass otherCls) {
        if(this.isPublic()) {
            return true;
        }

        if(this.isProtected()) {
            return this.getClazz().equals(otherCls) || otherCls.isSubClassOf(this.getClazz())
                    || this.getClazz().getPackageName().equals(otherCls.getPackageName());
        }

        if(!this.isPrivate()) {
            return this.getClazz().getPackageName().equals(otherCls.getPackageName());
        }

        return this.getClazz() == otherCls;
    }

    public boolean isPublic() {
        return 0 != (this.accessFlags & AccessFlag.ACC_PUBLIC);
    }

    public boolean isPrivate() {
        return 0 != (this.accessFlags & AccessFlag.ACC_PRIVATE);
    }

    public boolean isProtected() {
        return 0 != (this.accessFlags & AccessFlag.ACC_PROTECTED);
    }

    public boolean isStatic() {
        return 0 != (this.accessFlags & AccessFlag.ACC_STATIC);
    }

    public boolean isFinal() {
        return 0 != (this.accessFlags & AccessFlag.ACC_FINAL);
    }

    public boolean isSynthetic() {
        return 0 != (this.accessFlags & AccessFlag.ACC_SYNTHETIC);
    }

    public int getAccessFlags() {
        return accessFlags;
    }

    public String getName() {
        return name;
    }

    public String getDescriptor() {
        return descriptor;
    }

    public VMClass getClazz() {
        return clazz;
    }

    public void setAccessFlags(int accessFlags) {
        this.accessFlags = accessFlags;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setDescriptor(String descriptor) {
        this.descriptor = descriptor;
    }

    public void setClazz(VMClass clazz) {
        this.clazz = clazz;
    }

    public String getSignature() {
        return signature;
    }

    public void setSignature(String signature) {
        this.signature = signature;
    }

    public byte[] getAnnotationData() {
        return annotationData;
    }

    public void setAnnotationData(byte[] annotationData) {
        this.annotationData = annotationData;
    }
}
